/**
 * 
 */
package com.gragra.sequentiaDataGenerator;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * This segmenter kann be used to remove punctuation that has been added at the beginning or end of a word,
 * this punctuation will then be tagged with a special punctuation tag that must be given as an argument
 * when the class is created. the punctuation will have no other information associated to it, all ExtensionLevel
 * information that is associated to the string before punctuation is split off will be present only in the
 * array for the element from which punctuation was removed. the pattern used to remove punctuation is:
 * (\\p{Punct}*)(.*?)(\\p{Punct}*) all elements matching the first group or the third group will be split into
 * individual characters and added as punctuation. Punctuation is defined by the regex \p{Punct}. It is assumed
 * that all the information is seperated by "|".
 * @author Christoph Teichmann
 * created Mar 27, 2013 3:19:04 PM
 * @version 0.1
 */
public class PunctuationSplitOffSegmenter implements Segmentation
{
	/**
	 * the tag that will be assigned to all punctuation
	 */
	private final String punctTag;
	/**
	 * constructs a new instance with the given String used as the tag for any punctuation that has been split off
	 * at the end or beginning of a sentence
	 * @param punctTag
	 */
	public PunctuationSplitOffSegmenter(String punctTag)
	{
		super();
		this.punctTag = punctTag;
	}
	/**
	 * the pattern that is used to split of punctuation, one for every instance to make it a little more thread
	 * safe (as long as each thread only uses one instance)
	 */
	private final Pattern pa = Pattern.compile("(\\p{Punct}*)(.+?)(\\p{Punct}*)");
	/**
	 * the list that is used and reused to return the result of segmentation
	 */
	private final ObjectArrayList<String[]> ret = new ObjectArrayList<String[]>();
	/* (non-Javadoc)
	 * @see com.gragra.sequentiaDataGenerator.Segmentation#segment(java.lang.String)
	 */
	@Override
	public ObjectArrayList<String[]> segment(String s)
	{
		ret.clear();
		String[] full = s.split("\\|");
		String cont = full[0];
		Matcher ma = pa.matcher(cont);
		ma.matches();
		String sub1 = ma.group(1);
		String sub2 = ma.group(2);
		String sub3 = ma.group(3);
		String[] partsOfFirst = sub1.split("");
		String[] partsOfThird = sub3.split("");
		this.add(partsOfFirst);
		this.body(full, sub2);
		this.add(partsOfThird);
		return ret;
	}
	/**
	 * this method adds all the punctuation elements to the return. the array is either
	 * the split of all the leading or all the trailing punctuation
	 * @param full
	 * @param partsOfFirst
	 */
	protected void add(final String[] partsOfFirst)
	{
		for(int i=1;i<partsOfFirst.length;++i)
		{
			String q = partsOfFirst[i];
			String[] elems = new String[] {q,this.punctTag};
			ret.add(elems);
		}
	}
	/**
	 * this method is used to add Strings that are not split off punctuation to the return,
	 * q is the string that will be added and full is all the additional information, where
	 * full[0] is the original string and the following stuff is the tag and the ExtensionLevel information
	 * this method 
	 * @param full
	 * @param q
	 */
	protected void body(String[] full, String q)
	{
		String[] elems = Arrays.copyOf(full, full.length);
		elems[0] = q;
		ret.add(elems);
	}
}